﻿// ActionScript file
//--------------------------------------------------------------
//
// Qizhi Zhang 
// ezhung@gmail.com
// http://www.moorwind.com
//
//--------------------------------------------------------------
package com.moorwind.ai.math
{
    public class Matrix3x3
    {
        //////////////////////////////////////////////////////////////////////////////
        //Public properties
        public var e11:Number,e12:Number,e13:Number,e21:Number,e22:Number,e23:Number,e31:Number,e32:Number,e33:Number;
        
        /** 转置矩阵 */
        public function get transpose():Matrix3x3
        {
            return new Matrix3x3(e11,e21,e31,e12,e22,e32,e13,e23,e33);
        }
        
        /** 逆矩�?*/
        public function get inverse():Matrix3x3
        {
            var d:Number =     e11*e22*e33 - 
                            e11*e32*e23 + 
                            e21*e32*e13 - 
                            e21*e12*e33 + 
                            e31*e12*e23 - 
                            e31*e22*e13;
            if(d == 0 ) d = 1;
            
            return new Matrix3x3(    (e22*e33-e23*e32)/d,
                                    -(e12*e33-e13*e32)/d,
                                    (e12*e23-e13*e22)/d,
                                    -(e21*e33-e23*e31)/d,
                                    (e11*e33-e13*e31)/d,
                                    -(e11*e23-e13*e21)/d,
                                    (e21*e32-e22*e31)/d,
                                    -(e11*e32-e12*e31)/d,
                                    (e11*e22-e12*e21)/d );                    
        }
        
        /** 行列�?*/
        public function get det():Number
        {
            return    e11*e22*e33 - 
                    e11*e32*e23 + 
                    e21*e32*e13 - 
                    e21*e12*e33 + 
                    e31*e12*e23 - 
                    e31*e22*e13;    
        }
        
        //////////////////////////////////////////////////////////////////////////////
        //Constructor
        public function Matrix3x3(    r1c1:Number = 0,r1c2:Number = 0,r1c3:Number = 0,
                                    r2c1:Number = 0,r2c2:Number = 0,r2c3:Number = 0,
                                    r3c1:Number = 0,r3c2:Number = 0,r3c3:Number = 0)
        {
            this.e11 = r1c1;
            this.e12 = r1c2;
            this.e13 = r1c3;
            this.e21 = r2c1;
            this.e22 = r2c2;
            this.e23 = r2c3;
            this.e31 = r3c1;
            this.e32 = r3c2;
            this.e33 = r3c3;
        }
        
        //////////////////////////////////////////////////////////////////////////////
        //methods
        
        /** 矩阵+= */
        public function add(m:Matrix3x3):void
        {
            this.e11 += m.e11;
            this.e12 += m.e12;
            this.e13 += m.e13;
            this.e21 += m.e21;
            this.e22 += m.e22;
            this.e23 += m.e23;
            this.e31 += m.e31;
            this.e32 += m.e32;
            this.e33 += m.e33;
        }
        
        /** 矩阵-= */
        public function sub(m:Matrix3x3):void
        {
            this.e11 -= m.e11;
            this.e12 -= m.e12;
            this.e13 -= m.e13;
            this.e21 -= m.e21;
            this.e22 -= m.e22;
            this.e23 -= m.e23;
            this.e31 -= m.e31;
            this.e32 -= m.e32;
            this.e33 -= m.e33;
        }
        
        /** 矩阵×= */
        public function mul(s:Number):void
        {
            this.e11 *= s;
            this.e12 *= s;
            this.e13 *= s;
            this.e21 *= s;
            this.e22 *= s;
            this.e23 *= s;
            this.e31 *= s;
            this.e32 *= s;
            this.e33 *= s;
        }
        
        /** 矩阵/= */
        public function sub(s:Number):void
        {
            this.e11 /= s;
            this.e12 /= s;
            this.e13 /= s;
            this.e21 /= s;
            this.e22 /= s;
            this.e23 /= s;
            this.e31 /= s;
            this.e32 /= s;
            this.e33 /= s;
        }
        
        /** 矩阵相加 */
        public static function addition(m1:Matrix3x3, m2:Matrix3x3):Matrix3x3
        {
            return new Matrix3x3(    m1.e11 + m2.e11,
                                    m1.e12 + m2.e12,
                                    m1.e13 + m2.e13,
                                    m1.e21 + m2.e21,
                                    m1.e22 + m2.e22,
                                    m1.e23 + m2.e23,
                                    m1.e31 + m2.e31,
                                    m1.e32 + m2.e32,
                                    m1.e33 + m2.e33 );
        }
        
        /** 矩阵相减 */
        public static function subtraction(m1:Matrix3x3, m2:Matrix3x3):Matrix3x3
        {
            return new Matrix3x3(    m1.e11 - m2.e11,
                                    m1.e12 - m2.e12,
                                    m1.e13 - m2.e13,
                                    m1.e21 - m2.e21,
                                    m1.e22 - m2.e22,
                                    m1.e23 - m2.e23,
                                    m1.e31 - m2.e31,
                                    m1.e32 - m2.e32,
                                    m1.e33 - m2.e33 );
        }
        
        /** 矩阵相除 */
        public static function division(m:Matrix3x3, s:Number):void
        {
            return new Matrix3x3(    m.e11 / s,
                                    m.e12 / s,
                                    m.e13 / s,
                                    m.e21 / s,
                                    m.e22 / s,
                                    m.e23 / s,
                                    m.e31 / s,
                                    m.e32 / s,
                                    m.e33 / s );
        }
        
        /** 矩阵乘法 */
        public static function multiplication(m1:Matrix3x3, m2:Matrix3x3):Matrix3x3
        {
            return new Matrix3x3(    m1.e11*m2.e11 + m1.e12*m2.e21 + m1.e13*m2.e31,
                                    m1.e11*m2.e12 + m1.e12*m2.e22 + m1.e13*m2.e32,
                                    m1.e11*m2.e13 + m1.e12*m2.e23 + m1.e13*m2.e33,
                                    m1.e21*m2.e11 + m1.e22*m2.e21 + m1.e23*m2.e31,
                                    m1.e21*m2.e12 + m1.e22*m2.e22 + m1.e23*m2.e32,
                                    m1.e21*m2.e13 + m1.e22*m2.e23 + m1.e23*m2.e33,
                                    m1.e31*m2.e11 + m1.e32*m2.e21 + m1.e33*m2.e31,
                                    m1.e31*m2.e12 + m1.e32*m2.e22 + m1.e33*m2.e32,
                                    m1.e31*m2.e13 + m1.e32*m2.e23 + m1.e33*m2.e33 );
        }
        
        /** 矩阵乘法 */
        public static function MSMulti(m:Matrix3x3, s:Number):Matrix3x3
        {
            return new    Matrix3x3(    m.e11*s,
                                    m.e12*s,
                                    m.e13*s,
                                    m.e21*s,
                                    m.e22*s,
                                    m.e23*s,
                                    m.e31*s,
                                    m.e32*s,
                                    m.e33*s);
        }
        
        /** 矩阵乘法 */
        public static function SMMulti(s:Number, m:Matrix3x3):Matrix3x3
        {
            return new Matrix3x3(    m.e11*s,
                                    m.e12*s,
                                    m.e13*s,
                                    m.e21*s,
                                    m.e22*s,
                                    m.e23*s,
                                    m.e31*s,
                                    m.e32*s,
                                    m.e33*s);
        }
        
        /** 矩阵乘法 */
        public static function MVMulti(m:Matrix3x3, u:Vector):Vector
        {
            return new Vector(    m.e11*u.x + m.e12*u.y + m.e13*u.z,
                                m.e21*u.x + m.e22*u.y + m.e23*u.z,
                                m.e31*u.x + m.e32*u.y + m.e33*u.z);    
        }
        
        /** 矩阵乘法 */
        public static function VMMulti(u:Vector, m:Matrix3x3):Vector
        {
            return new Vector(    u.x*m.e11 + u.y*m.e21 + u.z*m.e31,
                                u.x*m.e12 + u.y*m.e22 + u.z*m.e32,
                                u.x*m.e13 + u.y*m.e23 + u.z*m.e33);
        }

    }
}